import React, { useState } from 'react'
import { useComponentsStore } from '../../stores/components'
import type { Component } from '../../stores/components'//将components仓库内的Component类型引入
import { useComponentConfigStore } from '../../stores/component-config'
import HoverMask from '../HoverMask'
import SelectedMask from '../SelectedMask'
export default function EditArea() {
  const { components ,setCurComponentId,curComponentId} = useComponentsStore()
  const { componentConfig } = useComponentConfigStore()
  const [hoverComponentId, setHoverComponentId] = useState<number>()//存放鼠标悬停组件的id
  //组件递归渲染
  function renderComponents(components: Component[]): React.ReactNode {//因为函数返回的是一个dom结构，所以使用React内置的ReactNode类型限制
    return components.map((component: Component) => {//拿到json数据进行遍历
      const config = componentConfig?.[component.name]//找到json数据中name在componentConfig中对应的组件
      if (!config?.dev) {//如果当前名字没有对应的组件
        return null
      }
      //渲染组件
      return React.createElement(config.dev, {
        key: component.id,//必须添加的key属性
        id: component.id,
        name: component.name,
        styles:component.styles,//组件的样式
        ...config.defaultProps,//组件的默认属性
        ...component.props,//组件的更新属性,会覆盖默认属性
      },
        renderComponents(component.children || [])//递归渲染整个json树，就是一直向下渲染它的子组件，知道没有为止
      )
    })
  }
  const handleMouseOver: React.MouseEventHandler = (e) => {
    const path = e.nativeEvent.composedPath()//拿到冒泡机制经历的所有容器的数组，数组排序为从内向外的容器
    for (let i = 0; i < path.length; i++) {
      const ele = path[i] as HTMLElement//拿到的DOM结构
      const componentId = ele.dataset&&ele.dataset.componentId//拿到鼠标放在的组件上的id,不是每个组件都有dataset
      if (componentId) {
        setHoverComponentId(Number(componentId))
        return
      }
    }
  }
  //借助冒泡机制，点击页面上的任何子组件，都会在父容器内记录所点击的是哪个子组件
  const handleClick: React.MouseEventHandler = (e) => {
    // console.log(e.nativeEvent.composedPath());
    const path = e.nativeEvent.composedPath()//拿到冒泡机制经历的所有容器的数组，数组排序为从内向外的容器
    for (let i = 0; i < path.length; i++) {
      const ele = path[i] as HTMLElement//拿到的DOM结构
      const componentId = ele.dataset&&ele.dataset.componentId//拿到鼠标放在的组件上的id，不是每个组件都有dataset
      if (componentId) {//找到第一个拥有componentId的容器
        setCurComponentId(Number(componentId))//将componentId赋值给仓库内的curComponentId
        return
      }
    }
  }
  return (
    <div className='h-[100%] edit-area' onMouseOver={handleMouseOver} onMouseLeave={() => { setHoverComponentId(undefined) }} onClick={handleClick}>
      {renderComponents(components)}
      {hoverComponentId && hoverComponentId !== curComponentId && (
        <HoverMask containerClassName='edit-area' componentId={hoverComponentId} portalWrapperClassName='portal-wrapper' />
      )}
      {curComponentId&&(
        <SelectedMask containerClassName='edit-area' componentId={curComponentId} portalWrapperClassName='portal-wrapper'/>
      )}
      <div className='portal-wrapper'></div>
    </div>
  )
}